/**
 *	---------------------------------------------------------------------------
 *	COMP 6231/FALL 2013
 *	Assignment - 02
 *	@author Talha Rahman (1296884)
 *	---------------------------------------------------------------------------
 *	This class processes each incoming UDP request to the server {@link StationServer}.
 *	This class extends the Thread class and runs concurrently - hence processing each
 *	UDP request in parallel. 
 *	  
 */
package ca.concordia.comp6231.udp;

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.SocketException;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import ca.concordia.comp6231.record.CriminalRecord;
import ca.concordia.comp6231.record.MissingRecord;
import ca.concordia.comp6231.record.Record;
import ca.concordia.comp6231.server.StationServer;
import ca.concordia.comp6231.server.StationServerCORBA;

public class UDPServiceRequestProcessor extends Thread {
	private StationServer rmiServer;
	private StationServerCORBA corbaServer;
	private String responseString;
	private DatagramSocket socket;
	private DatagramPacket request;

	public UDPServiceRequestProcessor(StationServer rmiServer, DatagramSocket socket, DatagramPacket request) {
		this.rmiServer = rmiServer;
		this.socket = socket;
		this.request = request;
	}
	
	public UDPServiceRequestProcessor(StationServerCORBA corbaServer, DatagramSocket socket, DatagramPacket request) {
		this.corbaServer = corbaServer;
		this.socket = socket;
		this.request = request;
	}

	@Override
	public void run() {
		String requestString = new String(request.getData());
		System.out.println("The request string is : " + requestString);
		String testString1 = "getRecordCount";
		String testString2 = "transferRecord";
		
		if (requestString.startsWith(testString1)) {
			responseString = getRecordCountString(corbaServer);
		}else if(requestString.trim().startsWith(testString2)){
			List<String> items = Arrays.asList(requestString.trim().split("\\="));
			String recordString = "";
			if(items.size() > 0){
				recordString = items.get(1).replaceAll("\\{", "").replaceAll("\\}", "");
			}
			responseString = transferRecord(recordString);
		}else{
			responseString = "Invalid Request.";
		}

		DatagramPacket reply = new DatagramPacket(responseString.getBytes(),
				responseString.length(), request.getAddress(),
				request.getPort());

		try {
			socket.send(reply);
		} catch (SocketException e) {
			System.out.println("Socket error: " + e.getMessage());
		} catch (IOException e) {
			System.out.println("IO error: " + e.getMessage());
		}
	}

	private String getRecordCountString(StationServer rmiServer) {
		String response = "";
		response = rmiServer.getServerName() + " "
				+ rmiServer.getRecordCountForCurrentServer();

		return response;
	}
	
	private String getRecordCountString(StationServerCORBA corbaServer) {
		String response = "";
		response = corbaServer.getServerName() + " "
				+ corbaServer.getRecordCountForCurrentServer();

		return response;
	}
	
	private String transferRecord(String recordString){
		String response = "";
		List<String> recordParams = Arrays.asList(recordString.trim().split(","));
		Map<String, String> recordParamMap = new HashMap<String, String>();
		for(String item : recordParams){
			List<String> dataParts = Arrays.asList(item.trim().split(":"));
			String label = dataParts.get(0).trim();
			String data = dataParts.get(1).trim();
			recordParamMap.put(label, data);
		}
		
		String recordID = recordParamMap.get("Record ID");
		String firstLetterOfLastName = "";
		boolean recordIDExists = (corbaServer.recordStore.findRecordByID(recordID) != null);
		Record record = null;
		if(recordID.startsWith("CR")){
			
			String ID;
			if(!recordIDExists){
				ID = recordID;
			}else{
				ID = corbaServer.generateID("CR");
			}
			
			String fName = recordParamMap.get("First Name");
			String lName = recordParamMap.get("Last Name");
			String crimeDesc = recordParamMap.get("Crime Description");
			String status = recordParamMap.get("Status");
			
			record = new CriminalRecord(ID, fName, lName, crimeDesc, status);
			firstLetterOfLastName = lName.substring(0, 1).toUpperCase();

		}else if(recordID.startsWith("MR")){
			
			String ID;
			if(!recordIDExists){
				ID = recordID;
			}else{
				ID = corbaServer.generateID("MR");
			}
			
			String fName = recordParamMap.get("First Name");
			String lName = recordParamMap.get("Last Name");
			String description = recordParamMap.get("Description");
			String status = recordParamMap.get("Status");
			String address = recordParamMap.get("Address");
			String lastDate = recordParamMap.get("Last Date");
			String lastLocation = recordParamMap.get("Last Location");
			
			record = new MissingRecord(ID, fName, lName, description, address, lastDate, lastLocation, status);
			firstLetterOfLastName = lName.substring(0, 1).toUpperCase();
		}
		
		try {
			corbaServer.recordStore.addNewRecord(firstLetterOfLastName.charAt(0), record);
			response = "Transferred record : " + record;
		} catch (Exception e) {
			response = "Failed to add new record : " + record;
		}
		
		return response;
	}

	public String getResponseString() {
		return responseString;
	}

}
